sgsR: Structurally Guided Sampling

Tristan Goodbody, Nicholas Coops, Martin Queinnec, Joanne White, Piotr Tompalski, Andrew Hudak, David Auty, Ruben Valbuena, Antoine LeBoeuf, Ian Sinclair, Grant McCartney, Jean-Francois Prieur, Murray Woods

University of British Columbia

Overview

  • Brief inventory and sampling overview

  • Discuss using auxiliary variables within sampling frameworks

  • Structurally guided sampling using Airborne Laser Scanning

  • sgsR overview

  • Programmatic examples of the package

Forest inventories

Purpose: Obtain knowledge about the population (forest area) under investigation and provide estimates of specific target variables.

Needed information: Defined by the scope & scale of the inventory. Answered by questions like:

  • Who/what is the information for? (e.g. Reporting obligations, timber production)

  • How big of an area are we inventorying? (e.g. National level, operational level)

Answers dictate the sampling approaches to fulfill inventory obligations and objectives.

Sampling

  • Mensuration is a cornerstone of forest management.
  • Sampling drives accurate forest attribute estimates (e.g. forest area, stem volume).

Sampling can be:

  • Labour intensive

  • Logistically challenging

  • Expensive

  • We want to balance these challenges with attribute estimate accuracy
  • Many sampling methods, but traditional and commonly used examples include:

Probability-based sampling

Common sampling methods include randomized sampling where probabilities for each sample unit are known and equivalent.

#--- simple random sampling ---#
sample_srs(raster = mr, nSamp = 100, plot = TRUE)

Systematic sampling

Systematic sampling methods are also common, where sample units are selected based on a defined distance.

#--- systematic sampling ---#
sample_systematic(raster = mr, cellsize = 1000, plot = TRUE)

Different tessellation shapes are fairly common

#--- systematic sampling in hexagons ---#
sample_systematic(raster = mr, cellsize = 1000, square = FALSE, plot = TRUE)

And combinations of systematic and simple random sampling also exists

#--- systematic random sampling ---#
sample_systematic(raster = mr, cellsize = 1000, 
                  square = FALSE, location = "random", plot = TRUE)

Auxiliary data

Probability-based sampling does not leverage auxiliary data such as:

  • Imagery, Feature-based inventories, ALS metrics (height, cover, variability)
  • Auxiliary data as a-priori information to guide model-based sampling has been fruitful.

The ALS data also provides an excellent source of prior information that may be used in the design phase of the field survey to reduce the size of the field data set. Gobakken et al. (2013)

Stratification

Stratification using auxiliary data can lead to representative sampling approaches.

Hawbaker et al. (2009)

Gobakken et al. (2013)

#--- perform stratification ---#
sraster <- strat_quantiles(mraster = mr$zq90, # p90
                           nStrata = 5) # 5 strata in p90

#--- perform stratification ---#
sraster <- strat_quantiles(mraster = mr$zq90, # p90
                           nStrata = 5) # 5 strata in p90

#--- perform stratification ---#
sraster <- strat_quantiles(mraster = mr$zq90, # p90
                           nStrata = 5) # 5 strata in p90

#--- perform dual metric stratification ---#
sraster <- strat_quantiles(mraster = mr$zq90, # p90
                           mraster2 = mr$zsd, # standard deviation of height
                           nStrata = 10, # 10 strata in p90
                           nStrata2 = 3) # 3 strata in zsd

#--- perform dual metric stratification ---#
sraster <- strat_quantiles(mraster = mr$zq90, # p90
                           mraster2 = mr$zsd, # standard deviation of height
                           nStrata = 10, # 10 strata in p90
                           nStrata2 = 3) # 3 strata in zsd

#--- perform dual metric stratification ---#
sraster <- strat_quantiles(mraster = mr$zq90, # p90
                           mraster2 = mr$zsd, # standard deviation of height
                           nStrata = 10, # 10 strata in p90
                           nStrata2 = 3) # 3 strata in zsd

Structurally guided sampling

#--- perform stratification ---#
sraster <- strat_quantiles(mraster = mr$zq90, # p90
                           mraster2 = mr$zsd, # standard deviation of height
                           nStrata = 10, # 10 strata in p90
                           nStrata2 = 3) # 3 strata in zsd

#--- structurally guided stratified sampling ---#
sample_strat(sraster = sraster, nSamp = 100, plot = TRUE)

sgsR

sgsR purpose

A growing number of studies have demonstrated that a-priori use of ALS metrics to guide sampling design provides methods that are:

  • transparent

  • repeatable

  • tuneable

  • spatially-explicit

sgsR is intended to provide a simple to use toolbox for practitioners to leverage these benefits to provide primarily model-based sampling approaches for forest inventories.

overview

Algorithm structure

  • sgsR was built using the terra, sf, & tidyverse packages

  • There are 4 primary function verbs that sgsR uses:

    • strat_* - apply stratification to metrics raster (mraster) and output a stratified raster (sraster)

    • sample_* - allocate samples using srasters produced from strat_* functions.

    • calculate_*- calculate sample information or create useful intermediary sampling products.

    • extract_* - extract pixels values from rasters to samples

Example 1 - Stratified sampling

Lets read in some ALS metrics

#--- Stratification ---#
#--- Load ALS metrics from sgsR internal data ---#
r <- system.file("extdata", "mraster.tif", package = "sgsR")

#--- Read ALS metrics using the terra package ---#
mraster <- terra::rast(r)

Example 1 - Stratified sampling

Lets read in some ALS metrics - mraster.

#--- Stratification ---#
#--- Load ALS metrics from sgsR internal data ---#
r <- system.file("extdata", "mraster.tif", package = "sgsR")

#--- Read ALS metrics using the terra package ---#
mraster <- terra::rast(r)

Lets also read in a linear road access network.

#--- Load access network from sgsR internal data ---#
a <- system.file("extdata", "access.shp", package = "sgsR")

#--- load the access vector using the sf package ---#
access <- sf::st_read(a)

Like before, lets stratify p90 in to 4 strata based on quantiles.

#--- perform stratification ---#
sraster <- strat_quantiles(mraster = mraster$zq90, # input ALS metric - p90
                           nStrata = 4) # desired number of strata (4)

Now lets use the sraster output.

#--- perform stratification ---#
sraster <- strat_quantiles(mraster = mraster$zq90, # input ALS metric - p90
                           nStrata = 4) # desired number of strata (4)

#--- perform sampling ---#
samples <- sample_strat(sraster = sraster, 
                        nSamp = 100, 
                        access = access, 
                        buff_inner = 50, 
                        buff_outer = 400)

Request 100 proportionally allocated samples.

#--- perform stratification ---#
sraster <- strat_quantiles(mraster = mraster$zq90, # input ALS metric - p90
                           nStrata = 4) # desired number of strata (4)

#--- perform sampling ---#
samples <- sample_strat(sraster = sraster, 
                        nSamp = 100, 
                        access = access, 
                        buff_inner = 50, 
                        buff_outer = 400)

Bring in the access road.

#--- perform stratification ---#
sraster <- strat_quantiles(mraster = mraster$zq90, # input ALS metric - p90
                           nStrata = 4) # desired number of strata (4)

#--- perform sampling ---#
samples <- sample_strat(sraster = sraster, 
                        nSamp = 100, 
                        access = access, 
                        buff_inner = 50, 
                        buff_outer = 400)

Specify we dont want samples within 50 m of access.

#--- perform stratification ---#
sraster <- strat_quantiles(mraster = mraster$zq90, # input ALS metric - p90
                           nStrata = 4) # desired number of strata (4)

#--- perform sampling ---#
samples <- sample_strat(sraster = sraster, 
                        nSamp = 100, 
                        access = access, 
                        buff_inner = 50, 
                        buff_outer = 400)

Or further than 400 m from access.

#--- perform stratification ---#
sraster <- strat_quantiles(mraster = mraster$zq90, # input ALS metric - p90
                           nStrata = 4) # desired number of strata (4)

#--- perform sampling ---#
samples <- sample_strat(sraster = sraster, 
                        nSamp = 100, 
                        access = access, 
                        buff_inner = 50, 
                        buff_outer = 400)

Example 1 - Stratified Sampling

Mapped result (A) and plotted result (B).

Note buffered access in A. Points are samples in both A & B.

Comparing distributions

When constraining by access its important to make sure that you’re still sampling the entire distribution of metrics.

  • We see that access constrained (green) and the full population (yellow) are very similar.

Existing samples

Practitioners may ask:

“I have an existing sample network, can I use those same sample locations?”

“If I go and visit those same sample units, where should I locate new samples for structural representation?”

Augmenting an existing sample

Lets create an existing sample of 50 plots using simple random sampling (sample_srs).

  • We are assuming these have been measured or used previously and can be revisited.
set.seed(2022)
#--- simple random sampling ---#
existing <- sample_srs(raster = mr, nSamp = 50, plot = TRUE)

Sampling and metric densities

Example 2 - existing

Augmenting an existing sample can be done using the Adapted Hypercube Evaluation of a Legacy Sample (AHELS) algorithm. Originally presented by Malone, Minansy & Brungard (2019).

sample_ahels() works by:

  • Determining representation of existing sample.

  • Determining number of additional samples that can / need to be added.

  • Generate quantile and covariance matrix of ALS metrics.

  • Identify where new samples are needed to balance quantile density and sampling density.

  • Iteratively locate samples.

We have our existing sample

#--- simple random sampling ---#
existing <- sample_srs(raster = mr, nSamp = 50, plot = TRUE)

Now we can use the sample_ahels() algorithm with our als metrics.

#--- simple random sampling ---#
existing <- sample_srs(raster = mr, nSamp = 50, plot = TRUE)

#--- augment sample network using sample_ahels ---#
#--- perform ahels sampling ---#
sample_ahels(mraster = mr,
             existing = existing,
             nSamp = 50)

Specify our existing sample.

#--- simple random sampling ---#
existing <- sample_srs(raster = mr, nSamp = 50, plot = TRUE)

#--- augment sample network using sample_ahels ---#
#--- perform ahels sampling ---#
sample_ahels(mraster = mr,
             existing = existing,
             nSamp = 50)

And specify we want 50 new sample units (nSamp).

#--- simple random sampling ---#
existing <- sample_srs(raster = mr, nSamp = 50, plot = TRUE)

#--- augment sample network using sample_ahels ---#
#--- perform ahels sampling ---#
sample_ahels(mraster = mr,
             existing = existing,
             nSamp = 50)

sample_ahels() result

Mapped result (A) and plotted result (B).

Note ratios (black/red) and additional added samples e.g n = 2 for each stratum.

sample_ahels() result

existing only (A) and addition of new samples (B).

We see that metric and sample density become quite even - structurally representative.

Summary

  • Structurally guided sampling methods show promise for model-based sampling
  • The sgsR package provides many methods to implement SGS approaches
  • We presented a few examples of sgsR functionality
  • If you want to know more feel free to come and talk to me, or use the link on the slide below for documentation and vignettes

Thank you!

Special thanks to the Canadian Wood Fibre Centre for funding this research!

My Twitter: @GoodbodyT

IRSS Twitter: @IRSS_UBC

Collaborators

  • Martin Queinnec
  • Joanne White
  • Andrew Hudak
  • Ruben Valbuena
  • Murray Woods
  • David Auty
  • Antoine Leboeuf
  • Ian Sinclair
  • Grant McCartney
  • Jean-Francois Prieur
  • Piotr Tompalski

Thank you!